﻿using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
using Ext.Net;
using Ext.Net.Utilities;

namespace KamLib.Controls
{

    public interface IUiFormFieldInfoAdapter
    {
        void Apply(UiFormFieldInfo info);
    }

    public class LogicLink
    {
        public string LID { get; set; }
        public string LIID { get; set; }

        public string[] KeyFields { get; set; }
        public string KeyField
        {
            get { return KeyFields != null ? KeyFields.Join(",") : null; }
            set { KeyFields = value != null ? value.Split(',') : null; }
        }

        public string[] LookupFields { get; set; }
        public string LookupField
        {
            get { return LookupFields != null ? LookupFields.Join(",") : null; }
            set { LookupFields = value != null ? value.Split(',') : null; }
        }

        public string[] MasterIDs { get; set; }
        /// <summary>
        /// LookupField1:MasterField1,LookupField2:MasterField2,... 
        /// </summary>
        public string MasterID
        {
            get { return MasterIDs != null ? MasterIDs.Join(",") : null; }
            set
            {
                MasterIDs = value != null ? value.Split(',') : null;
                if (MasterIDs == null)
                {
                    LookupMasterIDs = null;
                    return;
                }
                LookupMasterIDs = new string[MasterIDs.Length];
                for (var i = 0; i < MasterIDs.Length; ++i)
                {
                    var mm = MasterIDs[i].Split(':');
                    if (mm.Length > 1)
                    {
                        LookupMasterIDs[i] = mm[0];
                        MasterIDs[i] = mm[1];
                    }
                    else
                    {
                        LookupMasterIDs[i] = MasterIDs[i];
                    }
                }
            }
        }
        public string[] LookupMasterIDs { get; set; }
        public string LookupMasterID
        {
            get { return LookupMasterIDs != null ? LookupMasterIDs.Join(",") : null; }
            set { LookupMasterIDs = value != null ? value.Split(',') : null; }
        }


        public bool Active { get { return LookupField != null && LID != null && LIID != null && KeyField != null; } }

        /// <summary>
        /// Для быстрого задания [LookupField:][LID].[LIID].[KeyField] - писать в таком формате
        /// </summary>
        public string ID
        {
            get { return LID + "." + LIID + "." + KeyField; }
            set
            {
                if (value == null) return;
                var ids = value.Split(':');
                if (ids.Length > 1)
                {
                    LookupField = ids[0];
                    value = ids[1];
                }
                ids = value.Split('.');
                if (ids.Length > 0) LID = ids[0];
                if (ids.Length > 1) LIID = ids[1];
                if (ids.Length > 2) KeyField = ids[2];
            }
        }

    }


    #region Checks

    [ParseChildren(true, "Items")]
    public class CheckboxGroup : Ext.Net.CheckboxGroup
    {
        [PersistenceMode(PersistenceMode.InnerDefaultProperty)]
        public override ItemsCollection<Ext.Net.Checkbox> Items { get { return base.Items; } }
    }

    public class Checkbox : Ext.Net.Checkbox
    {
        [DefaultValue(typeof(Unit), "22")]
        public override Unit Height
        {
            get { return UnitPixelTypeCheck(ViewState["Height"], 22, "Height"); }
            set { base.Height = value; }
        }

        [DefaultValue("")]
        public string OnClientCheck
        {
            get { return Listeners.Check.Handler; }
            set { Listeners.Check.Handler = value; }
        }
    }

    [ParseChildren(true, "Items")]
    public class RadioGroup : Ext.Net.RadioGroup
    {
        [PersistenceMode(PersistenceMode.InnerDefaultProperty)]
        public override ItemsCollection<Ext.Net.Radio> Items { get { return base.Items; } }
    }

    public class Radio : Ext.Net.Radio
    {
        [DefaultValue(typeof(Unit), "22")]
        public override Unit Height
        {
            get { return UnitPixelTypeCheck(ViewState["Height"], 22, "Height"); }
            set { base.Height = value; }
        }
    }

    #endregion

    [ParseChildren(true, "Items")]
    public class RowField : CompositeField
    {
        [PersistenceMode(PersistenceMode.InnerDefaultProperty)]
        public override ItemsCollection<Ext.Net.Component> Items { get { return base.Items; } }
    }

    #region Text

    public class Text : DisplayField
    {
        //[DefaultValue(typeof(Unit), "22")]
        //public override Unit Height
        //{
        //    get { return UnitPixelTypeCheck(ViewState["Height"], 22, "Height"); }
        //    set { base.Height = value; }
        //}
    }

    public class TextNote : Text
    {
        [DefaultValue("x-field-note")]
        public override string Cls
        {
            get { return ViewState.Try("Cls", "x-field-note"); }
            set { base.Cls = value; }
        }
    }

    public class TextField : Ext.Net.TextField, IUiFormFieldInfoAdapter
    {
        void IUiFormFieldInfoAdapter.Apply(UiFormFieldInfo info)
        {
            AllowBlank = info.Nullable;
            if (MaxLength <= 0 || MaxLength > info.MaxLength)
                MaxLength = info.MaxLength;
        }
    }

    public class TextArea : Ext.Net.TextArea, IUiFormFieldInfoAdapter
    {
        void IUiFormFieldInfoAdapter.Apply(UiFormFieldInfo info)
        {
            AllowBlank = info.Nullable;
            if (MaxLength <= 0 || MaxLength > info.MaxLength)
                MaxLength = info.MaxLength;
        }
    }


    #endregion


    #region NumberFields

    public class NumberField : Ext.Net.NumberField, IUiFormFieldInfoAdapter
    {
        [DefaultValue(typeof(Unit), "60")]
        public override Unit Width
        {
            get { return UnitPixelTypeCheck(ViewState["Width"], 60, "Width"); }
            set { base.Width = value; }
        }

        void IUiFormFieldInfoAdapter.Apply(UiFormFieldInfo info)
        {
            AllowBlank = info.Nullable;
        }
    }


    public class FloatField : NumberField
    {
        [DefaultValue(-1)]
        public override int DecimalPrecision
        {
            get { return ViewState.Try("DecimalPrecision", -1); }
            set { base.DecimalPrecision = value; }
        }
    }

    public class Float1Field : NumberField
    {
        [DefaultValue(1)]
        public override int DecimalPrecision
        {
            get { return ViewState.Try("DecimalPrecision", 1); }
            set { base.DecimalPrecision = value; }
        }
    }

    public class Float2Field : NumberField
    {
        [DefaultValue(2)]
        public override int DecimalPrecision
        {
            get { return ViewState.Try("DecimalPrecision", 2); }
            set { base.DecimalPrecision = value; }
        }
    }

    public class Float3Field : NumberField
    {
        [DefaultValue(3)]
        public override int DecimalPrecision
        {
            get { return ViewState.Try("DecimalPrecision", 3); }
            set { base.DecimalPrecision = value; }
        }
    }

    public class Float4Field : NumberField
    {
        [DefaultValue(4)]
        public override int DecimalPrecision
        {
            get { return ViewState.Try("DecimalPrecision", 4); }
            set { base.DecimalPrecision = value; }
        }
    }

    public class Float5Field : NumberField
    {
        [DefaultValue(5)]
        public override int DecimalPrecision
        {
            get { return ViewState.Try("DecimalPrecision", 5); }
            set { base.DecimalPrecision = value; }
        }
    }

    public class Float6Field : NumberField
    {
        [DefaultValue(6)]
        public override int DecimalPrecision
        {
            get { return ViewState.Try("DecimalPrecision", 6); }
            set { base.DecimalPrecision = value; }
        }
    }

    public class Float7Field : NumberField
    {
        [DefaultValue(7)]
        public override int DecimalPrecision
        {
            get { return ViewState.Try("DecimalPrecision", 7); }
            set { base.DecimalPrecision = value; }
        }
    }

    public class Float8Field : NumberField
    {
        [DefaultValue(8)]
        public override int DecimalPrecision
        {
            get { return ViewState.Try("DecimalPrecision", 8); }
            set { base.DecimalPrecision = value; }
        }
    }

    public class Float9Field : NumberField
    {
        [DefaultValue(9)]
        public override int DecimalPrecision
        {
            get { return ViewState.Try("DecimalPrecision", 9); }
            set { base.DecimalPrecision = value; }
        }
    }

    public class Float10Field : NumberField
    {
        [DefaultValue(10)]
        public override int DecimalPrecision
        {
            get { return ViewState.Try("DecimalPrecision", 10); }
            set { base.DecimalPrecision = value; }
        }
    }


    public class IntField : NumberField
    {
        public override bool AllowDecimals { get { return false; } set { } }

        [DefaultValue(int.MaxValue)]
        public override double MaxValue
        {
            get { return ViewState.Try<double>("MaxValue", int.MaxValue); }
            set { base.MaxValue = value; }
        }

        [DefaultValue(int.MinValue)]
        public override double MinValue
        {
            get { return ViewState.Try<double>("MinValue", int.MinValue); }
            set { base.MinValue = value; }
        }
    }

    public class UIntField : IntField
    {
        [DefaultValue(0)]
        public override double MinValue
        {
            get { return ViewState.Try<double>("MinValue", 0); }
            set { base.MinValue = value; }
        }
    }

    public class PercField : NumberField
    {
        [DefaultValue(100)]
        public override double MaxValue
        {
            get { return ViewState.Try<double>("MaxValue", 100); }
            set { base.MaxValue = value; }
        }

        [DefaultValue(0)]
        public override double MinValue
        {
            get { return ViewState.Try<double>("MinValue", 0); }
            set { base.MinValue = value; }
        }
    }

    #endregion


    public class SelectBox : Ext.Net.SelectBox
    {
        public override string AnchorHorizontal
        {
            get { return ViewState.Try("AnchorHorizontal", "0"); }
            set { base.AnchorHorizontal = value; }
        }

        [DefaultValue("n")]
        public override string DisplayField
        {
            get { return ViewState.Try("DisplayField", "n"); }
            set { base.DisplayField = value; }
        }

        protected LogicLink _link = new LogicLink();
        [NotifyParentProperty(true)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public LogicLink Link { get { return _link; } }

        public override string Name
        {
            get { return base.Name; }
            set { base.Name = value; HiddenName = value; }
        }

        [DefaultValue("k")]
        public override string ValueField
        {
            get { return ViewState.Try("ValueField", "k"); }
            set { base.ValueField = value; }
        }

        private string _StoreClientID;
        [NotifyParentProperty(true)]
        public string StoreClientID
        {
            get { return _StoreClientID; }
            set
            {
                if (_StoreClientID == value) return;
                _StoreClientID = value;

                foreach (var item in CustomConfig)
                {
                    if (item.Name != "store") continue;
                    item.Value = value;
                    return;
                }

                CustomConfig.Add(new ConfigItem("store", value, ParameterMode.Raw));
            }
        }

        [DefaultValue(typeof(Unit), "60")]
        public override Unit Width
        {
            get { return UnitPixelTypeCheck(ViewState["Width"], 60, "Width"); }
            set { base.Width = value; }
        }

        protected override void OnBeforeClientInit(Observable sender)
        {
            base.OnBeforeClientInit(sender);

            if (Link.LookupField.IsEmpty()) Link.LookupField = HiddenName;
            if (Link.LookupField == "") Link.LookupField = null;

            if (Link.LIID.IsEmpty()) Link.LIID = "Form";

            if (Link.KeyField.IsEmpty()) Link.KeyField = Link.LookupField;
            if (Link.KeyField == "") Link.KeyField = null;

            if (Link.Active)
            {
                Triggers.Add(new FieldTrigger { Icon = TriggerIcon.Search, });
                Listeners.Change.Handler = "this.triggers[0][this.getValue().toString().length==0?'hide':'show']();";
                //Listeners.Select.Handler = "this.triggers[0].show();";
                Listeners.TriggerClick.Handler =
                    "if(index==0){KamLib.Logic.Form.editEntity({lid:'" + Link.LID + "',liid:'" + Link.LIID +
                    "',id:{" + Link.KeyField + ":this.getValue()}},false,this.getEl());}";
            }
        }
    }


    #region Time

    public class DateField : Ext.Net.DateField, IUiFormFieldInfoAdapter
    {
        [DefaultValue(typeof(Unit), "90")]
        public override Unit Width
        {
            get { return UnitPixelTypeCheck(ViewState["Width"], 90, "Width"); }
            set { base.Width = value; }
        }

        void IUiFormFieldInfoAdapter.Apply(UiFormFieldInfo info)
        {
            AllowBlank = info.Nullable;
        }
    }


    public class TimeField : Ext.Net.TimeField, IUiFormFieldInfoAdapter
    {
        [DefaultValue("H:i")]
        public override string Format
        {
            get { return ViewState.Try("Format", "HH:i"); }
            set { base.Format = value; }
        }
        public override string Name
        {
            get { return base.Name; }
            set { base.Name = value; HiddenName = value; }
        }
        [DefaultValue(typeof(Unit), "60")]
        public override Unit Width
        {
            get { return UnitPixelTypeCheck(ViewState["Width"], 60, "Width"); }
            set { base.Width = value; }
        }

        void IUiFormFieldInfoAdapter.Apply(UiFormFieldInfo info)
        {
            AllowBlank = info.Nullable;
        }
    }

    public class Time5Field : TimeField
    {
        [DefaultValue(5)]
        public override int Increment { get { return 5; } }
    }

    public class Time10Field : TimeField
    {
        [DefaultValue(10)]
        public override int Increment { get { return 10; } }
    }

    public class Time30Field : TimeField
    {
        [DefaultValue(30)]
        public override int Increment { get { return 30; } }
    }

    #endregion

}